﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Sockets;
using System.ServiceModel.Web;
using System.Threading;
using System.Windows.Forms;
using IdentityAtRest.Contracts;
using IdentityAtRest.Utility.Identity;
using IdentityAtRest.Utility.Identity.Wcf;

namespace ServiceConsumer
{
    public partial class ServiceConsumer : Form
    {
        private WebChannelFactory<IMonkeyShavingService> _channelFactory;
        private Process _service;

        public ServiceConsumer()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            InitializeChannelFactory();

            radAdministrator.Checked = true;
            ActiveControl = optMonkeyName;
        }

        private void InitializeChannelFactory()
        {
            WriteLine("Initialize client service...");

            _channelFactory = new WebChannelFactory<IMonkeyShavingService>("shavingService");
            _channelFactory.Endpoint.Behaviors.Add(new ClientAuthBehavior());

            WriteLine("Client service initialized");
        }

        private void WriteLine(string text)
        {
            txtOutput.Text += text + Environment.NewLine;
        }

        private void btnSubmitMonkey_Click(object sender, EventArgs e)
        {
            if (EnsureText(optMonkeyName, "Please choose a name for your monkey...") == false)
                return;

            try
            {
                IMonkeyShavingService proxy = _channelFactory.CreateChannel();
                Monkey monkey = proxy.PutMonkeyInShaver(new Monkey {Name = optMonkeyName.Text});

                txtOutput.Text = "";
                WriteLine(DateTime.Now + " :" + monkey.Message);

                optMonkeyName.Text = "";
                optMonkeyName.Items.Add(monkey.Name);
                ActiveControl = optMonkeyName;
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }

        private void btnSearchByName_Click(object sender, EventArgs e)
        {
            if (EnsureText(optMonkeyName, "Please enter the name of a monkey to search for...") == false)
                return;

            try
            {
                IMonkeyShavingService proxy = _channelFactory.CreateChannel();
                Monkey monkey = proxy.GetMonkey(optMonkeyName.Text);

                txtOutput.Text = "";
                if (monkey != null)
                    WriteMonkey(monkey, false);
                else
                    WriteLine("No monkey could be found with the requested name.");
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }

        private void btnBuyBeer_Click(object sender, EventArgs e)
        {
            if (EnsureText(optMonkeyName, "Please enter the name of a monkey to buy a beer for...") == false)
                return;

            try
            {
                IMonkeyShavingService proxy = _channelFactory.CreateChannel();
                string response = proxy.BuyMonkeyABeer(optMonkeyName.Text);

                txtOutput.Text = "";
                WriteLine(response);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }

        private void btnSearchByStatus_Click(object sender, EventArgs e)
        {
            try
            {
                IMonkeyShavingService proxy = _channelFactory.CreateChannel();
                IList<Monkey> monkeys = proxy.ListMonkeysByStatus(comboBox1.Text);
                txtOutput.Text = "";
                WriteLine("All monkeys with a status of " + comboBox1.Text + " :");
                foreach (Monkey m in monkeys)
                {
                    WriteMonkey(m, true);
                }
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }

        private void btnGetAllMonkeys_Click(object sender, EventArgs e)
        {
            try
            {
                IMonkeyShavingService proxy = _channelFactory.CreateChannel();
                IList<Monkey> monkeys = proxy.ListAllMonkeys();
                txtOutput.Text = "";
                foreach (Monkey m in monkeys)
                    WriteMonkey(m, false);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }

        private bool EnsureText(Control textbox, string error)
        {
            if (String.IsNullOrEmpty(textbox.Text))
            {
                MessageBox.Show(error);
                return false;
            }
            return true;
        }

        private void WriteMonkey(Monkey monkey, bool nameOnly)
        {
            if (nameOnly)
                WriteLine(monkey.Name);
            else
                WriteLine(monkey.Name + " is " + monkey.Status);
        }

        private void btnLaunchService_Click(object sender, EventArgs e)
        {
            _service = Process.Start("../../../ServiceHost/bin/debug/ServiceHost.exe");
        }

        private void ShowError(Exception ex)
        {
            while (ex.InnerException != null)
                ex = ex.InnerException;
            if (ex.GetType() != typeof (SocketException))
            {
                MessageBox.Show(ex.Message);
            }
            else
            {
                //No server running
                if (
                    MessageBox.Show(
                        "The service cannot be found. Would you like to launch the service host automatically?",
                        "Service Unavailable", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    btnLaunchService.PerformClick();
                }
            }
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            if (_service != null)
                _service.Kill();
        }

        private void radAnonymousUser_CheckedChanged(object sender, EventArgs e)
        {
            if (radAnonymousUser.Checked)
                Thread.CurrentPrincipal = null;
        }

        private void radRegularUser_CheckedChanged(object sender, EventArgs e)
        {
            if (radRegularUser.Checked)
                AuthenticationHelper.ImpersonateUser(new Claim(CustomClaimTypes.Role, "User"),
                                                     new Claim(CustomClaimTypes.AgeInYears, 23));
        }

        private void radAdministrator_CheckedChanged(object sender, EventArgs e)
        {
            if (radAdministrator.Checked)
                AuthenticationHelper.ImpersonateUser
                    (
                        new Claim(CustomClaimTypes.Role, "Administrator"),
                        new Claim(CustomClaimTypes.AgeInYears,35)
                     );
        }

        private void radUnderageAdministrator_CheckedChanged(object sender, EventArgs e)
        {
            if (radUnderageAdministrator.Checked)
                AuthenticationHelper.ImpersonateUser
                    (
                        new Claim(CustomClaimTypes.Role, "Administrator"),
                        new Claim(CustomClaimTypes.AgeInYears,13)
                    );
        }
      
        private void label4_Click(object sender, EventArgs e)
        {
        }

       

       

       
    }
}